import express from 'express';
import ResponseFormatter from '../utils/ResponseFormatter.js';

export class BaseRoute {
    constructor(service) {
        this.service = service;
        this.router = express.Router();
        this._setupRoutes();
    }

    /**
     * 子类需要重写此方法来设置具体的路由
     */
    _setupRoutes() {
        // 子类实现具体路由
    }

    /**
     * 获取路由器实例
     * @returns {Router} Express路由器
     */
    getRouter() {
        return this.router;
    }

    /**
     * 成功响应（委托给ResponseFormatter）
     * @param {Response} res - Express响应对象
     * @param {*} data - 响应数据
     * @param {string} message - 响应消息
     * @param {number} statusCode - HTTP状态码
     */
    success(res, data = null, message = 'Success', statusCode = 200) {
        return ResponseFormatter.success(res, data, message, statusCode);
    }

    /**
     * 错误响应（委托给ResponseFormatter）
     * @param {Response} res - Express响应对象
     * @param {string} message - 错误消息
     * @param {number} statusCode - HTTP状态码
     * @param {*} details - 错误详情
     */
    error(res, message = 'Internal Server Error', statusCode = 500, details = null) {
        return ResponseFormatter.error(res, message, statusCode, details);
    }

    /**
     * 验证错误响应（委托给ResponseFormatter）
     * @param {Response} res - Express响应对象
     * @param {*} errors - 验证错误详情
     * @param {string} message - 错误消息
     */
    validationError(res, errors = null, message = 'Validation failed') {
        return ResponseFormatter.validationError(res, errors, message);
    }

    /**
     * 未找到资源响应（委托给ResponseFormatter）
     * @param {Response} res - Express响应对象
     * @param {string} message - 错误消息
     */
    notFound(res, message = 'Resource not found') {
        return ResponseFormatter.notFound(res, message);
    }

    /**
     * 未授权响应（委托给ResponseFormatter）
     * @param {Response} res - Express响应对象
     * @param {string} message - 错误消息
     */
    unauthorized(res, message = 'Unauthorized') {
        return ResponseFormatter.unauthorized(res, message);
    }

    /**
     * 禁止访问响应（委托给ResponseFormatter）
     * @param {Response} res - Express响应对象
     * @param {string} message - 错误消息
     */
    forbidden(res, message = 'Forbidden') {
        return ResponseFormatter.forbidden(res, message);
    }

    /**
     * 冲突响应（委托给ResponseFormatter）
     * @param {Response} res - Express响应对象
     * @param {string} message - 错误消息
     */
    conflict(res, message = 'Conflict') {
        return ResponseFormatter.conflict(res, message);
    }

    /**
     * 通用异步路由处理器包装器
     * @param {Function} handler - 路由处理函数
     * @returns {Function} 包装后的处理函数
     */
    asyncHandler(handler) {
        return async (req, res, next) => {
            try {
                await handler(req, res, next);
            } catch (error) {
                this._handleError(res, error);
            }
        };
    }

    /**
     * 通用获取所有资源的路由处理器
     * @param {string} resourceName - 资源名称
     * @param {Function} serviceMethod - 服务方法
     * @returns {Function} 路由处理函数
     */
    getAll(resourceName, serviceMethod) {
        return this.asyncHandler(async (req, res) => {
            const { page = 1, limit = 10, ...filters } = req.query;
            
            const options = {
                page: parseInt(page),
                limit: parseInt(limit),
                ...filters
            };
            
            const result = await serviceMethod.call(this.service, options);
            
            this.success(res, result, `${resourceName} retrieved successfully`);
        });
    }

    /**
     * 通用根据ID获取资源的路由处理器
     * @param {string} resourceName - 资源名称
     * @param {Function} serviceMethod - 服务方法
     * @returns {Function} 路由处理函数
     */
    getById(resourceName, serviceMethod) {
        return this.asyncHandler(async (req, res) => {
            const { id } = req.params;
            
            if (!this._isValidId(id)) {
                return this.validationError(res, 'Invalid ID format');
            }
            
            const result = await serviceMethod.call(this.service, id);
            
            if (!result) {
                return this.notFound(res, `${resourceName} not found`);
            }
            
            this.success(res, result, `${resourceName} retrieved successfully`);
        });
    }

    /**
     * 通用创建资源的路由处理器
     * @param {string} resourceName - 资源名称
     * @param {Function} serviceMethod - 服务方法
     * @param {Function} validator - 验证函数
     * @returns {Function} 路由处理函数
     */
    create(resourceName, serviceMethod, validator = null) {
        return this.asyncHandler(async (req, res) => {
            const data = req.body;
            
            // 基础验证
            if (!data || Object.keys(data).length === 0) {
                return this.validationError(res, 'Request body cannot be empty');
            }
            
            // 自定义验证
            if (validator) {
                const validationResult = await validator(data);
                if (validationResult && !validationResult.isValid) {
                    return this.validationError(res, validationResult.message, validationResult.errors);
                }
            }
            
            const result = await serviceMethod.call(this.service, data);
            
            this.success(res, result, `${resourceName} created successfully`, 201);
        });
    }

    /**
     * 通用更新资源的路由处理器
     * @param {string} resourceName - 资源名称
     * @param {Function} serviceMethod - 服务方法
     * @param {Function} validator - 验证函数
     * @returns {Function} 路由处理函数
     */
    update(resourceName, serviceMethod, validator = null) {
        return this.asyncHandler(async (req, res) => {
            const { id } = req.params;
            const data = req.body;
            
            if (!this._isValidId(id)) {
                return this.validationError(res, 'Invalid ID format');
            }
            
            if (!data || Object.keys(data).length === 0) {
                return this.validationError(res, 'Request body cannot be empty');
            }
            
            // 自定义验证
            if (validator) {
                const validationResult = await validator(data, id);
                if (validationResult && !validationResult.isValid) {
                    return this.validationError(res, validationResult.message, validationResult.errors);
                }
            }
            
            const result = await serviceMethod.call(this.service, id, data);
            
            if (!result) {
                return this.notFound(res, `${resourceName} not found`);
            }
            
            this.success(res, result, `${resourceName} updated successfully`);
        });
    }

    /**
     * 通用删除资源的路由处理器
     * @param {string} resourceName - 资源名称
     * @param {Function} serviceMethod - 服务方法
     * @returns {Function} 路由处理函数
     */
    delete(resourceName, serviceMethod) {
        return this.asyncHandler(async (req, res) => {
            const { id } = req.params;
            
            if (!this._isValidId(id)) {
                return this.validationError(res, 'Invalid ID format');
            }
            
            const result = await serviceMethod.call(this.service, id);
            
            if (!result || result.affectedRows === 0) {
                return this.notFound(res, `${resourceName} not found`);
            }
            
            this.success(res, null, `${resourceName} deleted successfully`);
        });
    }

    /**
     * 批量操作路由处理器
     * @param {string} operation - 操作名称
     * @param {Function} serviceMethod - 服务方法
     * @returns {Function} 路由处理函数
     */
    batchOperation(operation, serviceMethod) {
        return this.asyncHandler(async (req, res) => {
            const { ids, ...data } = req.body;
            
            if (!Array.isArray(ids) || ids.length === 0) {
                return this.validationError(res, 'IDs array is required and cannot be empty');
            }
            
            // 验证所有ID
            const invalidIds = ids.filter(id => !this._isValidId(id));
            if (invalidIds.length > 0) {
                return this.validationError(res, `Invalid IDs: ${invalidIds.join(', ')}`);
            }
            
            const result = await serviceMethod.call(this.service, ids, data);
            
            this.success(res, result, `Batch ${operation} completed successfully`);
        });
    }

    /**
     * 参数验证中间件
     * @param {Object} rules - 验证规则
     * @returns {Function} 中间件函数
     */
    validateParams(rules) {
        return (req, res, next) => {
            const errors = [];
            
            Object.entries(rules).forEach(([param, rule]) => {
                const value = req.params[param] || req.query[param] || req.body[param];
                
                if (rule.required && (value === undefined || value === null || value === '')) {
                    errors.push(`${param} is required`);
                    return;
                }
                
                if (value !== undefined && value !== null && value !== '') {
                    if (rule.type === 'number' && isNaN(Number(value))) {
                        errors.push(`${param} must be a number`);
                    }
                    
                    if (rule.type === 'email' && !this._isValidEmail(value)) {
                        errors.push(`${param} must be a valid email`);
                    }
                    
                    if (rule.minLength && String(value).length < rule.minLength) {
                        errors.push(`${param} must be at least ${rule.minLength} characters`);
                    }
                    
                    if (rule.maxLength && String(value).length > rule.maxLength) {
                        errors.push(`${param} must not exceed ${rule.maxLength} characters`);
                    }
                }
            });
            
            if (errors.length > 0) {
                return this.validationError(res, 'Validation failed', errors);
            }
            
            next();
        };
    }

    /**
     * 处理错误
     * @param {Response} res - Express响应对象
     * @param {Error} error - 错误对象
     */
    _handleError(res, error) {
        console.error('Route Error:', error);
        
        // 根据错误类型返回不同的响应
        if (error.message.includes('not found') || error.message.includes('Not found')) {
            return this.notFound(res, error.message);
        }
        
        if (error.message.includes('Invalid') || error.message.includes('validation')) {
            return this.validationError(res, error.message);
        }
        
        if (error.message.includes('Unauthorized')) {
            return this.unauthorized(res, error.message);
        }
        
        if (error.message.includes('Forbidden')) {
            return this.forbidden(res, error.message);
        }
        
        if (error.message.includes('Conflict') || error.message.includes('already exists')) {
            return this.conflict(res, error.message);
        }
        
        // 默认服务器错误
        this.error(res, error.message, 500, process.env.NODE_ENV === 'development' ? error.stack : null);
    }

    /**
     * 验证ID格式
     * @param {*} id - ID值
     * @returns {boolean} 是否有效
     */
    _isValidId(id) {
        return id && (typeof id === 'number' || (typeof id === 'string' && /^\d+$/.test(id)));
    }

    /**
     * 验证邮箱格式
     * @param {string} email - 邮箱地址
     * @returns {boolean} 是否有效
     */
    _isValidEmail(email) {
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return emailRegex.test(email);
    }

    /**
     * 记录请求日志
     * @param {Request} req - Express请求对象
     * @param {string} action - 操作类型
     */
    _logRequest(req, action) {
        const logEntry = {
            timestamp: new Date().toISOString(),
            method: req.method,
            url: req.originalUrl,
            action,
            ip: req.ip,
            userAgent: req.get('User-Agent')
        };
        
        console.log('Request Log:', JSON.stringify(logEntry, null, 2));
    }
}